package netTools.logs;

import encryption.EncryptionManager;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import javax.security.auth.Subject;

import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.MessageProp;
import org.ietf.jgss.Oid;

public class RemoteLogger {

	public RemoteLogger(Subject sub) {
		this.subject = sub;
	}
	

	public void connect(String loggerAddr,int loggerPort,final String serviceName) throws UnknownHostException, IOException, GSSException{
		Socket s = new Socket(loggerAddr,loggerPort);
		inStream = new DataInputStream(s.getInputStream());
		outStream = new DataOutputStream(s.getOutputStream());

		try {
			GSSContext context = Subject.doAsPrivileged(subject, new PrivilegedExceptionAction<GSSContext>(){

				@Override
				public GSSContext run() throws Exception {
					GSSContext context = null;
					Oid krb5Oid = new Oid("1.2.840.113554.1.2.2");
					GSSManager manager = GSSManager.getInstance();
					GSSName serverGSSName = manager.createName(serviceName, null);
					context = manager.createContext(serverGSSName,krb5Oid,
							null,GSSContext.DEFAULT_LIFETIME);

					context.requestMutualAuth(true);
					context.requestConf(true);
					context.requestInteg(true);
					
					byte[] token = new byte[0];
					while (!context.isEstablished()) {
						// token is ignored on the first call
						token = context.initSecContext(token, 0, token.length);

						// Send a token to the server if one was generated by
						// initSecContext
						if (token != null) {
							outStream.writeInt(token.length);
							outStream.write(token);
							outStream.flush();
						}

						// If the client is done with context establishment
						// then there will be no more tokens to read in this loop
						if (!context.isEstablished()) {
							token = new byte[inStream.readInt()];
							inStream.readFully(token);
						}
					}
					
					return context;
				}
			}, null);
			em = new EncryptionManager(context,new MessageProp(0, true),0);
			
		} catch (PrivilegedActionException e) {
			e.printStackTrace();
		}

	}

	public void warning(String message) throws IOException{
		String m = "W/"+message;
		try {
			em.writeEncMessage(m.getBytes(), outStream);
		} catch (GSSException e) {
		}
	}

	public void info(String message) throws IOException{
		String m = "I/"+message;
		try {
			em.writeEncMessage(m.getBytes(), outStream);
		} catch (GSSException e) {
		}
	}

	public void severe(String message) throws IOException{
		String m = "S/"+message;
		try {
			em.writeEncMessage(m.getBytes(), outStream);
		} catch (GSSException e) {
		}
	}

	private Subject subject;
	private EncryptionManager em;
	private DataInputStream inStream;
	private DataOutputStream outStream;


}
